using Microsoft.AspNetCore.Http;
using System.Security.Claims;
using Microsoft.AspNetCore.Authentication;
using Microsoft.IdentityModel.Tokens;
using System.Text;
using Microsoft.IdentityModel.JsonWebTokens;

namespace MyBlogServer.Services
{
    public interface ISessionAuthService
    {
        Task<bool> SignInAsync(HttpContext httpContext, string username);
        Task SignOutAsync(HttpContext httpContext);
        bool IsAuthenticated(HttpContext httpContext);
        string GetUsername(HttpContext httpContext);
    }

    public class SessionAuthService : ISessionAuthService
    {
        private readonly string _secretKey;
        private readonly string _issuer;
        private readonly string _audience;
        private const string TokenKey = "JwtToken";

        public SessionAuthService(IConfiguration configuration)
        {
            _secretKey = configuration["Jwt:SecretKey"] ?? throw new ArgumentNullException(nameof(configuration));
            _issuer = configuration["Jwt:Issuer"] ?? throw new ArgumentNullException(nameof(configuration));
            _audience = configuration["Jwt:Audience"] ?? throw new ArgumentNullException(nameof(configuration));
        }

        public async Task<bool> SignInAsync(HttpContext httpContext, string username)
        {
            try
            {
                // 生成JWT Token
                var token = GenerateJwtToken(username);
                
                // 将Token存储在Session中
                httpContext.Session.SetString(TokenKey, token);
                return true;
            }
            catch (Exception ex)
            {
                Console.WriteLine($"JWT Token生成失败: {ex.Message}");
                return false;
            }
        }

        public async Task SignOutAsync(HttpContext httpContext)
        {
            try
            {
                // 清除Session中的Token
                httpContext.Session.Remove(TokenKey);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Token清除失败: {ex.Message}");
            }
        }

        public bool IsAuthenticated(HttpContext httpContext)
        {
            try
            {
                // 从Session中获取Token
                var token = httpContext.Session.GetString(TokenKey);
                if (string.IsNullOrEmpty(token))
                {
                    return false;
                }

                // 验证Token
                return IsTokenValid(token);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"检查认证状态时发生错误: {ex.Message}");
                return false;
            }
        }

        public string GetUsername(HttpContext httpContext)
        {
            try
            {
                // 从Session中获取Token
                var token = httpContext.Session.GetString(TokenKey);
                if (string.IsNullOrEmpty(token))
                {
                    return string.Empty;
                }

                // 验证并解析Token
                var tokenHandler = new JsonWebTokenHandler();
                var key = Encoding.ASCII.GetBytes(_secretKey);
                
                var validationParameters = new TokenValidationParameters
                {
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey = new SymmetricSecurityKey(key),
                    ValidateIssuer = true,
                    ValidIssuer = _issuer,
                    ValidateAudience = true,
                    ValidAudience = _audience,
                    ValidateLifetime = true,
                    ClockSkew = TimeSpan.Zero
                };

                var validationResult = tokenHandler.ValidateToken(token, validationParameters);
                if (!validationResult.IsValid)
                {
                    return string.Empty;
                }

                var jsonWebToken = (JsonWebToken)validationResult.SecurityToken;
                return jsonWebToken.Subject ?? string.Empty;
            }
            catch (Exception ex)
            {
                Console.WriteLine($"获取用户名时发生错误: {ex.Message}");
                return string.Empty;
            }
        }
        
        private string GenerateJwtToken(string username)
        {
            var tokenHandler = new JsonWebTokenHandler();
            var key = Encoding.ASCII.GetBytes(_secretKey);

            var tokenDescriptor = new SecurityTokenDescriptor
            {
                Subject = new ClaimsIdentity(new[]
                {
                    new Claim(ClaimTypes.Name, username),
                    new Claim(ClaimTypes.NameIdentifier, username)
                }),
                Expires = DateTime.UtcNow.AddHours(1),
                Issuer = _issuer,
                Audience = _audience,
                SigningCredentials = new SigningCredentials(
                    new SymmetricSecurityKey(key),
                    SecurityAlgorithms.HmacSha256Signature)
            };

            return tokenHandler.CreateToken(tokenDescriptor);
        }
        
        private bool IsTokenValid(string token)
        {
            try
            {
                var tokenHandler = new JsonWebTokenHandler();
                var key = Encoding.ASCII.GetBytes(_secretKey);
                
                var validationParameters = new TokenValidationParameters
                {
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey = new SymmetricSecurityKey(key),
                    ValidateIssuer = true,
                    ValidIssuer = _issuer,
                    ValidateAudience = true,
                    ValidAudience = _audience,
                    ValidateLifetime = true,
                    ClockSkew = TimeSpan.Zero
                };

                var validationResult = tokenHandler.ValidateToken(token, validationParameters);
                return validationResult.IsValid;
            }
            catch (Exception)
            {
                return false;
            }
        }
    }
}